/*
    This file is heavily modified by Bassoe,
	This file is part of the OdinMS Maple Story Server
    Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc> 
                       Matthias Butz <matze@odinms.de>
                       Jan Christian Meyer <vimes@odinms.de>

    This program is free sofstware: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
    as published by the Free Software Foundation. You may not use, modify
    or distribute this program under any other version of the
    GNU Affero General Public License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.sf.odinms.scripting.npc;

import java.awt.Point;
import java.util.LinkedList;
import java.util.List;
import java.util.Collection;
import java.util.Arrays;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import net.sf.odinms.client.Equip;
import net.sf.odinms.database.DatabaseConnection;


import net.sf.odinms.server.maps.MapleMapObject;
import net.sf.odinms.server.maps.MapleMapObjectType; 
import net.sf.odinms.net.PacketProcessor;
import net.sf.odinms.net.world.MapleParty;
import net.sf.odinms.net.world.MaplePartyCharacter;
import net.sf.odinms.client.IItem;
import net.sf.odinms.client.Item;
import net.sf.odinms.client.MapleCharacter;
import net.sf.odinms.client.MapleCharacterUtil;
import net.sf.odinms.client.MapleClient;
import net.sf.odinms.client.MapleInventory;
import net.sf.odinms.client.MapleInventoryType;
import net.sf.odinms.client.MapleJob;
import net.sf.odinms.client.MapleQuestStatus;
import net.sf.odinms.client.MapleRing;
import net.sf.odinms.client.SkillFactory;
import net.sf.odinms.net.world.guild.MapleGuild;
import net.sf.odinms.net.channel.ChannelServer;
import net.sf.odinms.scripting.AbstractPlayerInteraction;
import net.sf.odinms.scripting.event.EventManager;
import net.sf.odinms.server.MapleInventoryManipulator;
import net.sf.odinms.server.MapleItemInformationProvider;
import net.sf.odinms.server.MaplePortal;
import net.sf.odinms.server.MapleShopFactory;
import net.sf.odinms.server.TimerManager;
import net.sf.odinms.server.quest.MapleQuest;
import net.sf.odinms.tools.MaplePacketCreator;
import net.sf.odinms.client.MapleStat;
import net.sf.odinms.server.MapleSquad;
import net.sf.odinms.server.MapleSquadType;
//import net.sf.odinms.server.life.MapleLifeFactory;
//import net.sf.odinms.server.life.MapleMonster;
import net.sf.odinms.server.MapleStatEffect;
import net.sf.odinms.server.maps.MapleMap;
import net.sf.odinms.server.maps.SavedLocationType;
import net.sf.odinms.server.life.MapleMonsterStats;
import net.sf.odinms.server.life.MapleMonster;
import net.sf.odinms.server.life.MapleLifeFactory;
import net.sf.odinms.server.maps.FakeCharacter;

import net.sf.odinms.server.maps.MapleMapFactory;
import net.sf.odinms.server.maps.MapleMapItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 *
 * @author Matze
 */
public class NPCConversationManager extends AbstractPlayerInteraction {
    private static Logger log = LoggerFactory.getLogger(PacketProcessor.class);
    private MapleClient c;
    //private int redmesos;
    //private int bluemesos;
	private int npc;
	private String getText;
    //private MapleCharacter character;

	public NPCConversationManager(MapleClient c, int npc) {
		super(c);
        this.c = c;
		this.npc = npc;
	}

	public void dispose() {
		NPCScriptManager.getInstance().dispose(this);
	}

	public void sendNext(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 01"));
	}

	public void sendPrev(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 00"));
	}

	public void sendNextPrev(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "01 01"));
	}

	public void sendOk(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0, text, "00 00"));
	}

	public void sendYesNo(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 1, text, ""));
	}

	public void sendAcceptDecline(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 0x0C, text, ""));
	}

	public void sendSimple(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalk(npc, (byte) 4, text, ""));
	}

	public void sendStyle(String text, int styles[]) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalkStyle(npc, text, styles));
	}

	public void sendGetNumber(String text, int def, int min, int max) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalkNum(npc, text, def, min, max));
	}

	public void sendGetText(String text) {
		getClient().getSession().write(MaplePacketCreator.getNPCTalkText(npc, text));
	}

    public void sendInvite2v2(int mapid) {
            MapleMap map = getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld());
            MapleCharacter inviter = getPlayer();
            MapleCharacter member2 = getPlayer();
            //for (MaplePartyCharacter party : getPlayer().getParty().getMembers()) {
                //inviter = party;
            //}
            for (MapleCharacter player : map.getCharacters()) {
                if (player.getParty().getLeader() == player.getParty().getMemberById(player.getId())) {
                    sendAcceptDecline("#b" + inviter.getName() + " / Level " + inviter.getLevel() + " / " + inviter.getJob().name() + "\r\n" + member2.getName() + " / Level " + member2.getLevel() + " / " + member2.getJob().name() + "#k\r\n\r\nWould you like to battle this party at the Monster Carnival?");
                }
            }
    }

	public void setGetText(String text) {
		this.getText = text;
	}

	public String getText() {
		return this.getText;
	}

	public void openShop(int id) {
		MapleShopFactory.getInstance().getShop(id).sendShop(getClient());
	}
        
    public void playMusic(String music) {
        getPlayer().getMap().broadcastMessage(MaplePacketCreator.musicChange(music));
	}

	public void changeJob(MapleJob job) {
		getPlayer().changeJob(job);
	}

	public MapleJob getJob() {
		return getPlayer().getJob();
	}

    public int job() {
        return getPlayer().getJob().getId();
    }
        
    public int isDonator() {
            return getPlayer().isDonator();
    }

	public void startQuest(int id) {
		MapleQuest.getInstance(id).start(getPlayer(), npc);
	}

	public void completeQuest(int id) {
		MapleQuest.getInstance(id).complete(getPlayer(), npc);
	}

	public void forfeitQuest(int id) {
		MapleQuest.getInstance(id).forfeit(getPlayer());
	}
        
    public int getBombPoints() {
        return c.getPlayer().getBombPoints();
    }

    public void setBombPoints(int bombpoints) {
        c.getPlayer().setBombPoints(bombpoints);
    }

    public void startBombPVP(short amount, int pvpmap) {
        gainItem(2100067, amount);
        setBombPoints(5);
        warp(pvpmap);
    }

    public void warpMC() {
            ChannelServer cserv = c.getChannelServer();
            MapleMap target = cserv.getMapFactory().getMap(980000000, c.getPlayer().getWorld());
            MaplePortal targetPortal = target.getPortal(0);
            MapleCharacter player = c.getPlayer();
            c.getPlayer().saveLocation(SavedLocationType.MC);
            player.changeMap(target, targetPortal);
    }

    public void warpMap(int mapid, int portal) {
            MapleMap outMap;
            MapleMapFactory mapFactory;
            mapFactory = ChannelServer.getInstance(c.getChannel()).getMapFactory();
            outMap = mapFactory.getMap(mapid, c.getPlayer().getWorld());
            for (MapleCharacter aaa : outMap.getCharacters()) {
                //Warp everyone out
                mapFactory = ChannelServer.getInstance(aaa.getClient().getChannel()).getMapFactory();
                aaa.getClient().getPlayer().changeMap(outMap, outMap.getPortal(portal));
                outMap = mapFactory.getMap(mapid, c.getPlayer().getWorld());
                aaa.getClient().getPlayer().getEventInstance().unregisterPlayer(aaa.getClient().getPlayer()); //Unregister them all
            }
    }

    public MapleCharacter getCharByName(String namee) {
       try {
        return getClient().getChannelServer().getPlayerStorage().getCharacterByName(namee);
       } catch (Exception e) {
           return null;
       }
    }
        
    @Override
    public void mapMessage(String message) {
        c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(0, message));
    }

    public void warpWedding() {
        ChannelServer cserv = c.getChannelServer();
        MapleMap target = cserv.getMapFactory().getMap(680000210, c.getPlayer().getWorld());
        MaplePortal targetPortal;
        if (c.getPlayer().getWeddingType() == 1) targetPortal = target.getPortal(2);
        else targetPortal = target.getPortal(0);
        if (getPlayer().getParty() != null) {
            for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
                MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
                lol.changeMap(target, targetPortal);
            }
        } else
            c.getPlayer().changeMap(target, targetPortal);
    }

    public void startClock(int minutes) {
        c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.getClock(minutes * 60));
    }

    public void startClock(int hours, int minutes, int seconds) {
        c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.getClockTime(1, 2, 3));
    }
    public int getWeddingType() {
        return c.getPlayer().getWeddingType();
    }

    public void setWeddingType(int how) {//1 is marry, 0 is guest
        c.getPlayer().setWeddingType(how);
    }

    public boolean canMarry() {
        if (c.getPlayer().haveItem(5251000) && getPartyMembers() == 2 && c.getPlayer().isBlessed() == 1 && c.getPlayer().isMarried() == 0) return true;
        return false;
    }

    public void worldNotice(String notice) {
        try {
            ChannelServer.getInstance(c.getChannel()).getWorldInterface().broadcastMessage(c.getPlayer().getName(), notice.getBytes());
        } catch (RemoteException e) {
            c.getChannelServer().reconnectWorld();
        }
    }

    public int getPartyMembers() {
        MapleParty party = c.getPlayer().getParty();
        Collection<MaplePartyCharacter> membersC = party.getMembers();
        MaplePartyCharacter MPCmembers[] = membersC.toArray(new MaplePartyCharacter[membersC.size()]);
        return MPCmembers.length;
    }
    
    public void warpParty(int mapid) {
        for (MaplePartyCharacter plaa : getPlayer().getParty().getMembers()) {
            MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), plaa.getName());
            lol.changeMap(lol.getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld()), lol.getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld()).getPortal(0));
        }
    }

    public void warpPartyWithExp(int mapid, int exp) {
        for (MaplePartyCharacter plaa : c.getPlayer().getParty().getMembers()) {
            MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), plaa.getName());
            lol.changeMap(lol.getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld()), lol.getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld()).getPortal(0));
            lol.gainExp(exp, true, false, true);
        }
    }

    public void warpPartyWithExpMeso(int mapid, int exp, int meso) {
        for (MaplePartyCharacter plaa : c.getPlayer().getParty().getMembers()) {
            MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), plaa.getName());
            lol.changeMap(lol.getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld()), lol.getClient().getChannelServer().getMapFactory().getMap(mapid, c.getPlayer().getWorld()).getPortal(0));
            lol.gainExp(exp, true, false, true);
            lol.gainMeso(meso, true);
        }
    }

    public int getCharQuantity(int ismap) {
        MapleMap map = getPlayer().getClient().getChannelServer().getMapFactory().getMap(ismap, c.getPlayer().getWorld()) ;
        double range = Double.POSITIVE_INFINITY;
        List<MapleMapObject> players = map.getMapObjectsInRange(c.getPlayer().getPosition (), range, Arrays.asList(MapleMapObjectType.PLAYER));
        return players.size();
    }

    public void giveClone(String name) {
        FakeCharacter fc = new FakeCharacter(name, c.getPlayer(), c.getPlayer().getId() + c.getPlayer().getFakeChars().size() + 1);
        c.getPlayer().addFakeChar(fc);
        charNotice("Please walk to make it appear");
    }

    public void startTimer(final int map, long delay) {
        TimerManager.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                getPlayer().changeMap(getPlayer().getClient().getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld()), getPlayer().getClient().getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld()).getPortal(0));
            }
        }, delay);
    }

    public void startTimer(final int from, final int to, long delay) {
        TimerManager.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                if (getPlayer().getMapId() == from)
                    getPlayer().changeMap(getPlayer().getClient().getChannelServer().getMapFactory().getMap(to, c.getPlayer().getWorld()), getPlayer().getClient().getChannelServer().getMapFactory().getMap(to, c.getPlayer().getWorld()).getPortal(0));
            }
        }, delay);
    }

    public void startPartyTimer(final int map, long delay) {
        TimerManager.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
                    MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
                    lol.changeMap(lol.getClient().getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld()), lol.getClient().getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld()).getPortal(0));
                }
            }
        }, delay);
    }

    public void startPartyTimer(final int from, final int to, long delay) {
        TimerManager.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
                    MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
                    if (lol.getMapId() == from)
                        lol.changeMap(lol.getClient().getChannelServer().getMapFactory().getMap(to, c.getPlayer().getWorld()), lol.getClient().getChannelServer().getMapFactory().getMap(to, c.getPlayer().getWorld()).getPortal(0));

                }
            }
        }, delay);
    }

    public void reloadChar() { // Basically !fakerelog in NPC function form.
        getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(getPlayer()));
        getPlayer().getMap().removePlayer(getPlayer());
        getPlayer().getMap().addPlayer(getPlayer());
    }

    public boolean setName(String name) {
        if (MapleCharacterUtil.canCreateChar(name, c.getWorld()) == true) {
            getPlayer().setName(name);
            getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(6, "You're name is succesfully changed into " + name + ", enjoy"));
            getPlayer().saveToDB(true);
            return true;
        } else {
            getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(6, "Error, " + name + " is either a GM name, or it is already taken"));
            dispose();
            return false;
        }
    }


        
	/**
	 * use getPlayer().getMeso() instead
	 * @return
	 */
	@Deprecated
	public int getMeso() {
		return getPlayer().getMeso();
	}

    public void gainNX(int nxcash) {
        getPlayer().gainNX(nxcash);
	}
	
	public void gainMeso(int gain) {
		getPlayer().gainMeso(gain, true, false, true);
	}

	public void gainExp(int gain) {
		getPlayer().gainExp(gain, true, true);
	}
        
    public void setFame(int fame) {
            getPlayer().setFame(fame);
            getPlayer().updateSingleStat(MapleStat.FAME, Integer.valueOf(fame));
    }

    public void gainFame(int fame) {
            getPlayer().gainFame(fame);
            getPlayer().updateSingleStat(MapleStat.FAME, Integer.valueOf(getPlayer().getFame()));
            getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(6, "You have gained (+" + fame +") fame."));
    }

    public void gainAp(int ap) {
            getPlayer().gainAp(ap);
    }

    public void gainSp(int sp) {
            getPlayer().setRemainingSp(getPlayer().getRemainingSp() + sp);
    }

    public void charNotice(String Text) {
        getPlayer().getClient().getSession().write(MaplePacketCreator.serverNotice(6, Text));
    }

    public void modifyNX(int amount, int type) {
        getPlayer().modifyCSPoints(type, amount);
        if (amount > 0) {
                    getClient().getSession().write(MaplePacketCreator.serverNotice(5, "You have gained NX Cash (+" + amount +")."));
             } else {
                    getClient().getSession().write(MaplePacketCreator.serverNotice(5, "You have lost NX Cash (" + (amount) +")."));
             }
    }

    public int getNpc() {
        return npc;
    }

    public void spawnMob(int mobid) {
        MapleMonster npcmob = MapleLifeFactory.getMonster(mobid, c.getPlayer().getWorld());
        getPlayer().getMap().spawnMonsterOnGroundBelow(npcmob, getPlayer().getPosition());
    }

    public void spawnMob(int mobid, int ammount) {
        for (int i = 0; i < ammount; i++) {
            MapleMonster npcmob = MapleLifeFactory.getMonster(mobid, c.getPlayer().getWorld());
            getPlayer().getMap().spawnMonsterOnGroundBelow(npcmob, getPlayer().getPosition());
        }
    }

    public void spawnMob(int mobid, int HP, int MP, int level, int EXP, int boss, int undead, int amount, int x, int y) {
            MapleMonsterStats newStats = new MapleMonsterStats();
            Point spawnPos = new Point(x,y);
            if (HP != 0) {
                    newStats.setHp(HP);
            }
            if (MP != 0) {
                    newStats.setMp(MP);
            }
            if (level != 0) {
                    newStats.setLevel(level);
            }
            if (EXP != 0) {
                    newStats.setExp(EXP);
            }
            if (boss == 1) {
                    newStats.setBoss(true);
            }
            if (undead == 1) {
                    newStats.setUndead(true);
            }
            for (int i = 0; i < amount; i++) {
                    MapleMonster npcmob = MapleLifeFactory.getMonster(mobid, c.getPlayer().getWorld());
                    npcmob.setOverrideStats(newStats);
                    npcmob.setHp(npcmob.getMaxHp());
                    npcmob.setMp(npcmob.getMaxMp());
                    getPlayer().getMap().spawnMonsterOnGroundBelow(npcmob, spawnPos);
            }
    }

    public void createEquip(int itemid, int str, int dex, int intt, int luk) {
        createEquip(itemid, 0, 0, dex, 0, 0, intt, 0, 0, luk, 0, 0, 0, 0, str, 0, 0, 7);
    }

    public void createEquip(int itemid, int acc, int avoid, int dex, int hands, int hp, int intt, int jump, int level, int luk, int matk, int mdef, int mp, int speed, int str, int watk, int wdef, int upgradeslots) {
        if (getPlayer().getInventory(MapleInventoryType.EQUIP).isFull()) {
            charNotice("Your inventory is full");
            dispose();
        } else {
            Equip equip = new Equip(itemid, (byte) 0, -1);
            equip.setOwner(getPlayer().getName());
            equip.setQuantity((short) 1);
            equip.setAcc((short) acc);
            equip.setAvoid((short) avoid);
            equip.setDex((short) dex);
            equip.setHands((short) hands);
            equip.setHp((short) hp);
            equip.setInt((short) intt);
            equip.setJump((short) jump);
            equip.setLuk((short) luk);
            equip.setMatk((short) matk);
            equip.setMdef((short) mdef);
            equip.setMp((short) mp);
            equip.setSpeed((short) speed);
            equip.setStr((short) str);
            equip.setWatk((short) watk);
            equip.setWdef((short) wdef);
            equip.setUpgradeSlots((byte) upgradeslots);
            equip.setLevel((byte) level);
            MapleInventoryManipulator.addFromDrop(getClient(), equip, "");
        }
    }

    public void createRing(int itemid, String partner) {
        int partnerId = MapleCharacter.getIdByName(partner, 0);
        MapleCharacter partnerz = c.getChannelServer().getPlayerStorage().getCharacterByName(partner);
        if (partnerz.isMarried() == 0 && partnerz.isBlessed() == 1) {
            int[] ret = MapleRing.createRing(c, itemid, c.getPlayer().getId(), c.getPlayer().getName(), partnerId, partner);
            if (ret[0] == -1 || ret[1] == -1) {
                return;
            }
        } else {
            getPlayer().dropMessage("He/She already is married or haven't received blessings yet");
        }
    }

    public void advance1() {
        if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.SPEARMAN)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.DRAGONKNIGHT);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.FIGHTER)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.CRUSADER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.PAGE)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.WHITEKNIGHT);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.CLERIC)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.PRIEST);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.FP_WIZARD)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.FP_MAGE);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.IL_WIZARD)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.IL_MAGE);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.HUNTER)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.RANGER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.CROSSBOWMAN)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.SNIPER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.ASSASSIN)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.HERMIT);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BANDIT)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.CHIEFBANDIT);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.DRAGONKNIGHT)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.DARKKNIGHT);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.WHITEKNIGHT)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.PALADIN);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.CRUSADER)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.HERO);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.FP_MAGE)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.FP_ARCHMAGE);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.IL_MAGE)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.IL_ARCHMAGE);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.PRIEST)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.BISHOP);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.RANGER)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.BOWMASTER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.SNIPER)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.CROSSBOWMASTER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.HERMIT)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.NIGHTLORD);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.CHIEFBANDIT)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.SHADOWER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.INFIGHTER)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.BUCCANEER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.GUNSLINGER)) {
            if (c.getPlayer().getLevel() >= 70) {
                changeJob(net.sf.odinms.client.MapleJob.VALKYRIE);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                sendOk("You aren't level 70 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BUCCANEER)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.VIPER);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.VALKYRIE)) {
            if (c.getPlayer().getLevel() >= 120) {
                changeJob(net.sf.odinms.client.MapleJob.CAPTAIN);
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                maxSkills();
                dispose();
            } else {
                sendOk("You aren't level 120 or higher");
                dispose();
            }
        } else if (c.getPlayer().isFourthJob()) {
            sendOk("Hello there, and welcome to ChickenMS");
            dispose();
        } else {
            if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BEGINNER)) {
                sendSimple("Hey there #b" + c.getPlayer().getName() + "#k, Welcome to ChickenMS!\r\nWhat Job do you want to be?\r\n#b#L1#I want to be a Warrior!#l\r\n#L2#I want to be a Magician!#l\r\n#L3#I want to be a Bowman!#l\r\n#L4#I want to be a Thief!#l\r\n#L5#I want to be a Pirate!#l#k");
            } else {
                advance2(1);
            }
        }

    }

    public void advance2(int selection) {
        if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BEGINNER)) {
            if (c.getPlayer().getLevel() >= 10 || (selection == 2 && c.getPlayer().getLevel() >= 8)) {
                if (selection == 1) {
                    changeJob(net.sf.odinms.client.MapleJob.WARRIOR);
                    sendOk("Congratz on becoming a Warrior\r\nEnjoy ChickenMS!");
                    dispose();
                } else if (selection == 2) {
                    changeJob(net.sf.odinms.client.MapleJob.MAGICIAN);
                    sendOk("Congratz on becoming a Magician\r\nEnjoy ChickenMS!");
                    dispose();
                } else if (selection == 3) {
                    changeJob(net.sf.odinms.client.MapleJob.BOWMAN);
                    sendOk("Congratz on becoming a Bowman\r\nEnjoy ChickenMS!");
                    dispose();
                } else if (selection == 4) {
                    changeJob(net.sf.odinms.client.MapleJob.THIEF);
                    sendOk("Congratz on becoming a Thief\r\nEnjoy ChickenMS!");
                    dispose();
                } else {
                    changeJob(net.sf.odinms.client.MapleJob.PIRATE);
                    sendOk("Congratz on becoming a Pirate\r\nEnjoy ChickenMS!");
                    dispose();
                }
            } else {
                sendOk("Meh, you need to be atleast level 10 or 8 as Magician!");
                dispose();
            }
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.WARRIOR)) {
            sendSimple("Hey there #b" + c.getPlayer().getName() + "#k, Welcome to ChickenMS!\r\nWhat Job do you want to be?\r\n#b#L1#I want to be a Fighter!#l\r\n#L2#I want to be a Page!#l\r\n#L3#I want to be a Spearman!#l#k");
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.MAGICIAN)) {
            sendSimple("Hey there #b" + c.getPlayer().getName() + "#k, Welcome to ChickenMS!\r\nWhat Job do you want to be?\r\n#b#L1#I want to be a Fire Poison Wizard!#l\r\n#L2#I want to be a Ice Lightning Wizard!#l\r\n#L3#I want to be a Cleric!#l#k");
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BOWMAN)) {
            sendSimple("Hey there #b" + c.getPlayer().getName() + "#k, Welcome to ChickenMS!\r\nWhat Job do you want to be?\r\n#b#L1#I want to be a Hunter!#l\r\n#L2#I want to be a CrossbowMan!#l#k");
        } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.THIEF)) {
            sendSimple("Hey there #b" + c.getPlayer().getName() + "#k, Welcome to ChickenMS!\r\nWhat Job do you want to be?\r\n#b#L1#I want to be an Assassin!#l\r\n#L2#I want to be a Bandit!#l#k");
        } else {
            sendSimple("Hey there #b" + c.getPlayer().getName() + "#k, Welcome to ChickenMS!\r\nWhat Job do you want to be?\r\n#b#L1#I want to be a Brawler!#l\r\n#L2#I want to be a Gunslinger!#l#k");
        }
    }

    public void advance3(int selection) {
        if (c.getPlayer().getLevel() >= 30) {
            if (selection == 1) {
                if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.WARRIOR)) {
                    changeJob(net.sf.odinms.client.MapleJob.FIGHTER);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.MAGICIAN)) {
                    changeJob(net.sf.odinms.client.MapleJob.FP_WIZARD);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BOWMAN)) {
                    changeJob(net.sf.odinms.client.MapleJob.HUNTER);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.THIEF)) {
                    changeJob(net.sf.odinms.client.MapleJob.ASSASSIN);
                } else {
                    changeJob(net.sf.odinms.client.MapleJob.INFIGHTER);
                }
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else if (selection == 2) {
                if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.WARRIOR)) {
                    changeJob(net.sf.odinms.client.MapleJob.PAGE);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.MAGICIAN)) {
                    changeJob(net.sf.odinms.client.MapleJob.IL_WIZARD);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.BOWMAN)) {
                    changeJob(net.sf.odinms.client.MapleJob.CROSSBOWMAN);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.THIEF)) {
                    changeJob(net.sf.odinms.client.MapleJob.BANDIT);
                } else {
                    changeJob(net.sf.odinms.client.MapleJob.GUNSLINGER);
                }
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            } else {
                if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.WARRIOR)) {
                    changeJob(net.sf.odinms.client.MapleJob.SPEARMAN);
                } else if (c.getPlayer().getJob().equals(net.sf.odinms.client.MapleJob.MAGICIAN)) {
                    changeJob(net.sf.odinms.client.MapleJob.CLERIC);
                } else {
                    sendOk("Goodbye");
                    dispose();
                    return;
                }
                sendOk("Congratz on becoming the next job\r\nEnjoy ChickenMS!");
                dispose();
            }
        } else {
            sendOk("Meh, you need to be atleast level 30!");
            dispose();
        }
    }


	/**
	 * use getPlayer().getLevel() instead
	 * @return
	 */
	@Deprecated
	public int getLevel() {
		return getPlayer().getLevel();
	}

	public void unequipEverything() {
		MapleInventory equipped = getPlayer().getInventory(MapleInventoryType.EQUIPPED);
		MapleInventory equip = getPlayer().getInventory(MapleInventoryType.EQUIP);
		List<Byte> ids = new LinkedList<Byte>();
		for (IItem item : equipped.list()) {
			ids.add(item.getPosition());
		}
		for (byte id : ids) {
			MapleInventoryManipulator.unequip(getC(), id, equip.getNextFreeSlot());
		}
	}

	public void teachSkill(int id, int level, int masterlevel) {
		getPlayer().changeSkillLevel(SkillFactory.getSkill(id), level, masterlevel);
	}
        
    public void kill() {
            getPlayer().setHp(0);
            getPlayer().setMp(0);
            getPlayer().updateSingleStat(MapleStat.HP, 0);
            getPlayer().updateSingleStat(MapleStat.MP, 0);
    }

	/**
	 * Use getPlayer() instead (for consistency with MapleClient)
	 * @return
	 */
	@Deprecated
	public MapleCharacter getChar() {
		return getPlayer();
	}

	public MapleClient getC() {
		return getClient();
	}

	public void rechargeStars() {
		MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
		IItem stars = getChar().getInventory(MapleInventoryType.USE).getItem((byte) 1);
		if (ii.isThrowingStar(stars.getItemId()) || ii.isBullet(stars.getItemId())) {
			stars.setQuantity(ii.getSlotMax(stars.getItemId()));
			getC().getSession().write(MaplePacketCreator.updateInventorySlot(MapleInventoryType.USE, (Item) stars));
		}
	}

	public EventManager getEventManager(String event) {
		return getClient().getChannelServer().getEventSM().getEventManager(event);
	}
	
	public void showEffect(String effect) {
		getPlayer().getMap().broadcastMessage(MaplePacketCreator.showEffect(effect));
	}
	
	public void playSound(String sound) {
		getClient().getPlayer().getMap().broadcastMessage(MaplePacketCreator.playSound(sound));
	}
	
	@Override
	public String toString() {
		return "Conversation with NPC: " + npc;
	}
        
    public void updateBuddyCapacity(int capacity) {
        getPlayer().setBuddyCapacity(capacity);
    }
        
    public void displayGuildRanks() {
		MapleGuild.displayGuildRanks(getClient(), npc);
	}
        
    public int getBuddyCapacity() {
        return getPlayer().getBuddyCapacity();
    }

    public void setHair(int hair) {
        c.getPlayer().setHair(hair);
        c.getPlayer().updateSingleStat(MapleStat.HAIR, hair);
        c.getPlayer().equipChanged();
	}
        
    public int getHair() {
        return getPlayer().getHair();
	}
	
	public void setFace(int face) {
	        c.getPlayer().setFace(face);
	        c.getPlayer().updateSingleStat(MapleStat.FACE, face);
	        c.getPlayer().equipChanged();
	}
        
    public int getFace() {
        return getPlayer().getFace();
	}
	
	@SuppressWarnings("static-access")
	public void setSkin(int color) {            
	        c.getPlayer().setSkinColor(c.getPlayer().getSkinColor().getById(color));
	        c.getPlayer().updateSingleStat(MapleStat.SKIN, color);
	        c.getPlayer().equipChanged();
	}
        
	public MapleSquad createMapleSquad(MapleSquadType type) {
		MapleSquad squad = new MapleSquad(c.getChannel(), getPlayer());
		if (getSquadState(type) == 0) {
			c.getChannelServer().addMapleSquad(squad, type);
		} else {
			return null;
		}
		return squad;
	}


    public MapleSquad getSquad(MapleSquadType Type) {
        return c.getChannelServer().getMapleSquad(Type);
    }
        
	public MapleCharacter getSquadMember(MapleSquadType type, int index) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		MapleCharacter ret = null;
		if (squad != null) {
			ret = squad.getMembers().get(index);
		}
		return ret;
	}
	
	public int getSquadState(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			return squad.getStatus();
		} else {
			return 0;
		}
        }
        
        public void setSquadState(MapleSquadType type, int state) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			squad.setStatus(state);
		}
        }
        
        public boolean checkSquadLeader(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			if (squad.getLeader().getId() == getPlayer().getId()) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
        }

        public void removeMapleSquad(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			if (squad.getLeader().getId() == getPlayer().getId()) {
				squad.clear();
				c.getChannelServer().removeMapleSquad(squad, type);
			}
		}
        }
        
        public int numSquadMembers(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		int ret = 0;
		if (squad != null) {
			ret = squad.getSquadSize();
		}
		return ret;
        }
	
	public boolean isSquadMember(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		boolean ret = false;
		if (squad.containsMember(getPlayer())) {
			ret = true;
		}
		return ret;
	}
        
        public void addSquadMember(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			squad.addMember(getPlayer());
		}
        }

	public void removeSquadMember(MapleSquadType type, MapleCharacter chr, boolean ban) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			squad.banMember(chr, ban);
		}
	}
	
	public void removeSquadMember(MapleSquadType type, int index, boolean ban) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			MapleCharacter chr = squad.getMembers().get(index);
			squad.banMember(chr, ban);
		}
	}

	public boolean canAddSquadMember(MapleSquadType type) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		if (squad != null) {
			if (squad.isBanned(getPlayer())) {
				return false;
			} else {
				return true;
			}
		}
		return false;
	}
	
	public void warpSquadMembers(MapleSquadType type, int mapId) {
		MapleSquad squad = c.getChannelServer().getMapleSquad(type);
		MapleMap map = c.getChannelServer().getMapFactory().getMap(mapId, c.getPlayer().getWorld());
		if (squad != null) {
			if (checkSquadLeader(type)) {
				for (MapleCharacter chr : squad.getMembers()) {
					chr.changeMap(map, map.getPortal(0));
				}
			}
		}
	}

        public void resetReactors() {
		c.getPlayer().getMap().resetReactors();
	}
        
    public int itemQuantity(int itemid) {
            MapleInventoryType type = MapleItemInformationProvider.getInstance().getInventoryType(itemid);
            MapleInventory iv = getPlayer().getInventory(type);
            int possesed = iv.countById(itemid);
            return possesed;
    }

    public void setLevel(int level) {
        getPlayer().setLevel(level);
        getPlayer().updateSingleStat(MapleStat.LEVEL, Integer.valueOf(getPlayer().getLevel()));
    }

    public void levelup() {
        getPlayer().levelUp();
    }

    public boolean getConnetChar(String str) throws RemoteException {
        return c.getChannelServer().getPlayerStorage().getCharacterByName(str) != null;
    }

    public void chatNotice(String str, int type, String text) {
        MapleCharacter chr = c.getChannelServer().getPlayerStorage().getCharacterByName(str);
        chr.getClient().getSession().write(MaplePacketCreator.serverNotice(type, text));
    }

    public String getImageChar(byte mode, byte type, int sel) {
        MapleInventory equip = c.getPlayer().getInventory(MapleInventoryType.getByType(mode));
        if (equip.getItem((byte) type) != null && !(equip.getItem(type).getItemId() >= 2060000 && equip.getItem(type).getItemId() <= 2080000)) { // && equip.getItem(type).getQuantity() <= 100) {
            return "#L"+sel+"##i"+equip.getItem((byte) (type)).getItemId()+"##l";
        } else {
            return "";
        }
    }

    public String getImageChar(byte mode, byte type) {
        MapleInventory equip = c.getPlayer().getInventory(MapleInventoryType.getByType(mode));
        if (equip.getItem((byte) type) != null && !(equip.getItem(type).getItemId() >= 2060000 && equip.getItem(type).getItemId() <= 2080000)) { // && equip.getItem(type).getQuantity() <= 100) {
            return "#i"+equip.getItem((byte) (type)).getItemId()+"#";
        } else {
            return "";
        }
    }

    public String getQuaChar(byte mode, byte type) {
        MapleInventory equip = c.getPlayer().getInventory(MapleInventoryType.getByType(mode));
        if (equip.getItem((byte) type) != null && equip.getItem(type).getQuantity() <= 100) {
            return equip.getItem((byte) (type)).getQuantity()+"";
        } else if (equip.getItem((byte) type) != null && equip.getItem(type).getQuantity() > 100) {
            return "100";
        } else {
            return "";
        }
    }

    public String getInvenChar(byte mode, byte type) {
        MapleInventory equip = c.getPlayer().getInventory(MapleInventoryType.getByType(mode));
        if (equip.getItem((byte) type) != null) {
            return equip.getItem((byte) (type)).getItemId()+"";
        } else {
            return "";
        }
    }

    public void gainItem(String str, byte mode, int id, short quantity) {
        MapleCharacter chr = c.getChannelServer().getPlayerStorage().getCharacterByName(str);
        StringBuilder logInfo = new StringBuilder(chr.getName());
        logInfo.append(" received ");
        logInfo.append(quantity);
        logInfo.append(" from a scripted PlayerInteraction (");
        logInfo.append(this.toString());
        logInfo.append(")");
        MapleInventoryManipulator.addById(c, chr.getName(), id, quantity, logInfo.toString());
        chr.getClient().getSession().write(MaplePacketCreator.getShowItemGain(id,quantity, true));
    }

    public boolean getInvenFull(String str, byte type) {
        MapleCharacter chr = c.getChannelServer().getPlayerStorage().getCharacterByName(str);
        return chr.getInventory(MapleInventoryType.getByType(type )).isFull();
    }

    public String getName() {
        return getPlayer().getName();
    }

    public void killall() {
        killall(false);
    }

    public void killall(boolean drop) {
        c.getPlayer().getMap().killAllMonsters(drop);
    }

    public void killmap() {
        MapleMap map = c.getPlayer().getMap();
        double range = Double.POSITIVE_INFINITY;
        List<MapleMapObject> players = map.getMapObjectsInRange(c.getPlayer().getPosition(), range, Arrays.asList(MapleMapObjectType.PLAYER));
        for (MapleMapObject player : players) {
            MapleCharacter person = (MapleCharacter) player;
            person.setHp(0);
            person.updateSingleStat(MapleStat.HP, 0);
            person.dropMessage("You and the rest of the map have been killed by " + c.getPlayer().getName());
        }
    }

    public String getRankings(String job) {
        try {
            int int1 = 0;
            int int2 = 0;
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("SELECT * FROM characters WHERE job >= ? AND job <= ? AND gm = 0 ORDER BY level,reborns DESC LIMIT 10");
            if (job.equals("warrior")) {
                int1 = 100;
                int2 = 132;
            } else if (job.equals("magician")) {
                int1 = 200;
                int2 = 232;
            } else if (job.equals("bowman")) {
                int1 = 300;
                int2 = 322;
            } else if (job.equals("thief")) {
                int1 = 400;
                int2 = 422;
            } else if (job.equals("pirate")) {
                int1 = 500;
                int2 = 522;
            } else if (job.equals("beginner")) {
                int1 = 0;
                int2 = 0;
            } else if (job.equals("me")) {
                PreparedStatement ps2 = con.prepareStatement("SELECT name FROM characters ORDER BY level,reborns DESC");
                ResultSet rs = ps2.executeQuery();
                int i = 0;
                int lol = 0;
                while (rs.next()) {
                    i++;
                    if (rs.getString("name").equals(c.getPlayer().getName())) {
                        lol = i;
                        break;
                    }
                }
                rs.close();
                ps2.close();
                ps.close();
                return ("Your current rank is: " + lol);
            } else {
                ps.close();
                return "";
            }
            ps.setInt(1, int1);
            ps.setInt(2, int2);
            ResultSet rs = ps.executeQuery();
            int i = 0;
            StringBuffer buf = new StringBuffer();
            buf.append("");
            while (rs.next()) {
                i++;
                buf.append(i + ") " + rs.getString("name") + ", level: " + rs.getInt("level") + ", reborns: " + rs.getInt("reborns") + "\r\n");
            }
            rs.close();
            ps.close();
            return buf.toString();
        } catch (SQLException e) {
            return "Unknown error, please report this to the admin";
        }
    }

    public void retrieveItems() {
        for (MapleMapObject lol : c.getPlayer().getMap().getItemsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY)) {
            MapleMapItem item = (MapleMapItem) lol;
            if (item.getDropper() == c.getPlayer()) {
                if (MapleInventoryManipulator.addFromDrop(c, item.getItem(), "")) {
                    c.getPlayer().getMap().broadcastMessage(
                    MaplePacketCreator.removeItemFromMap(item.getObjectId(), 2, c.getPlayer().getId()),
                    item.getPosition());
                    c.getPlayer().getCheatTracker().pickupComplete();
                    c.getPlayer().getMap().removeMapObject(item);
                } else {
                    c.getPlayer().getCheatTracker().pickupComplete();
                }
                item.setPickedUp(true);
            }
        }
    }

    public void sendPacket(String packet) {
        c.getSession().write(MaplePacketCreator.customPacket(packet));
    }

    public void maxSkills() {
        teachSkill(1121000,0,5);
        teachSkill(1121001,0,5);
        teachSkill(1121002,0,5);
        teachSkill(1120003,0,5);
        teachSkill(1120004,0,5);
        teachSkill(1120005,0,5);
        teachSkill(1121006,0,5);
        teachSkill(1121008,0,5);
        teachSkill(1121010,0,5);
        teachSkill(1121011,0,1);
        teachSkill(1221000,0,5);
        teachSkill(1221001,0,5);
        teachSkill(1221002,0,5);
        teachSkill(1221003,0,5);
        teachSkill(1221004,0,5);
        teachSkill(1220005,0,5);
        teachSkill(1220006,0,5);
        teachSkill(1221007,0,5);
        teachSkill(1221009,0,5);
        teachSkill(1220010,0,5);
        teachSkill(1221011,0,5);
        teachSkill(1221012,0,1);
        teachSkill(1321000,0,5);
        teachSkill(1321001,0,5);
        teachSkill(1321002,0,5);
        teachSkill(1321003,0,5);
        teachSkill(1320005,0,5);
        teachSkill(1320006,0,5);
        teachSkill(1321007,0,5);
        teachSkill(1320008,0,5);
        teachSkill(1320009,0,5);
        teachSkill(1321010,0,1);
        teachSkill(2121000,0,5);
        teachSkill(2121001,0,5);
        teachSkill(2121002,0,5);
        teachSkill(2121003,0,5);
        teachSkill(2121004,0,5);
        teachSkill(2121005,0,5);
        teachSkill(2121006,0,5);
        teachSkill(2121007,0,5);
        teachSkill(2121008,0,1);
        teachSkill(2221000,0,5);
        teachSkill(2221001,0,5);
        teachSkill(2221002,0,5);
        teachSkill(2221003,0,5);
        teachSkill(2221004,0,5);
        teachSkill(2221005,0,5);
        teachSkill(2221006,0,5);
        teachSkill(2221007,0,5);
        teachSkill(2221008,0,1);
        teachSkill(2321000,0,5);
        teachSkill(2321001,0,5);
        teachSkill(2321002,0,5);
        teachSkill(2321003,0,5);
        teachSkill(2321004,0,5);
        teachSkill(2321005,0,5);
        teachSkill(2321006,0,5);
        teachSkill(2321007,0,5);
        teachSkill(2321008,0,5);
        teachSkill(2321009,0,1);
        teachSkill(3121000,0,5);
        teachSkill(3121002,0,5);
        teachSkill(3121003,0,5);
        teachSkill(3121004,0,5);
        teachSkill(3120005,0,5);
        teachSkill(3121006,0,5);
        teachSkill(3121007,0,5);
        teachSkill(3121008,0,5);
        teachSkill(3121009,0,1);
        teachSkill(3221000,0,5);
        teachSkill(3221001,0,5);
        teachSkill(3221002,0,5);
        teachSkill(3221003,0,5);
        teachSkill(3220004,0,5);
        teachSkill(3221005,0,5);
        teachSkill(3221006,0,5);
        teachSkill(3221007,0,5);
        teachSkill(3221008,0,1);
        teachSkill(4121000,0,5);
        teachSkill(4120002,0,5);
        teachSkill(4121003,0,5);
        teachSkill(4121004,0,5);
        teachSkill(4120005,0,5);
        teachSkill(4121006,0,5);
        teachSkill(4121007,0,5);
        teachSkill(4121008,0,5);
        teachSkill(4121009,0,1);
        teachSkill(4221000,0,5);
        teachSkill(4221001,0,5);
        teachSkill(4220002,0,5);
        teachSkill(4221003,0,5);
        teachSkill(4221004,0,5);
        teachSkill(4220005,0,5);
        teachSkill(4221006,0,5);
        teachSkill(4221007,0,5);
        teachSkill(4221008,0,1);
        teachSkill(5121000,0,5);
        teachSkill(5121001,0,5);
        teachSkill(5121002,0,5);//energy orb
        teachSkill(5121003,0,5);
        teachSkill(5121004,0,5);
        teachSkill(5121005,0,5);
        teachSkill(5121007,0,5);
        teachSkill(5121008,0,1);
        teachSkill(5121009,0,5);
        teachSkill(5121010,0,5);
        teachSkill(5221000,0,5);
        teachSkill(5220001,0,5);
        teachSkill(5220002,0,5);
        teachSkill(5221003,0,5);
        teachSkill(5221004,0,5);
        teachSkill(5221006,0,5);
        teachSkill(5221007,0,5);
        teachSkill(5221008,0,5);
        teachSkill(5221009,0,5);//hypnotize
        teachSkill(5221010,0,1);
        teachSkill(5220011,0,5);
    }

    public int countMonster() {
        return c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER)).size();
    }

    public void giveNPCBuff(MapleCharacter chr, int itemID) {
        MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
        MapleStatEffect statEffect = mii.getItemEffect(itemID);
        statEffect.applyTo(chr);
    }

    public void giveItemBuff(int itemid) {
        MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
        MapleStatEffect ah = ii.getItemEffect(itemid);
        ah.applyTo(c.getPlayer());
    }

    public String greenCharacters(String characters) {
        String[] letters = new String[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","-"," ","\\","?",",","."};
        int[] items = new int[69];
        for (int i = 0; i < 25; i++) {
            items[i] = (3991026 + i);
        }
        for (int a = 0; a < 25; a++) {
            items[a+26] = (3991026 + a);
        }
        for (int u = 0; u < 9; u++) {
            items[u+53] = (3990010 + u);
        }
        items[62] = 3990022;
        items[63] = 3990023;
        items[64] = 0;
        items[65] = 1;
        items[66] = 2;
        items[67] = 3;
        items[68] = 4;
        StringBuffer buf = new StringBuffer();
        buf.append("");
        for (int z = 0; z < characters.length(); z++) {
            for (int h = 0; h < letters.length; h++) {
                if (characters.substring(z, (z+1)).equals(letters[h])) {
                    if (items[h] > 4) {
                        buf.append("#v" + items[h] + "#");
                    } else if (items[h] == 0) {
                        buf.append("   ");
                    } else if (items[h] == 1) {
                        buf.append("\r\n");
                    } else if (items[h] == 2) {
                        buf.append("?");
                    } else if (items[h] == 3) {
                        buf.append(",");
                    } else if (items[h] == 4) {
                        buf.append(".");
                    }
                }
            }
        }
        return buf.toString();
    }

    public int getRandom(int start, int end) {
        return (int)Math.floor(Math.random()*end+start);
    }

    public void createAlliance(String name) {
        getPlayer().getGuild().createAlliance(getClient(), name);
    }

    public void sendAllianceInvite(String charname) {
        MapleCharacter z = c.getChannelServer().getPlayerStorage().getCharacterByName(charname);
        if (z != null) {
            if (z.getGuild().getLeader(z.getClient()) == z) {
               z.dropMessage(getPlayer().getName() + " invites your guild to join his alliance");
               z.dropMessage("If you want to accept that offer type @accept, else type @decline");
               z.setAllianceInvited(getPlayer().getGuild().getAlliance(getPlayer().getClient()));
            } else
                getPlayer().dropMessage("That character is not the leader of the guild");
        } else {
            getPlayer().dropMessage("That character is offline");
        }
    }

    public String checkCPQMaps() {
        StringBuffer buf = new StringBuffer();
        buf.append("Sign up for Monster Carnival!#b");
        for (int i = 0; i < 6; i++) {
            if (getCharQuantity((980000100 + (100 * i))) > 0) {
                buf.append("\r\n#L" + i + "# Join Carnival Field " + (i + 1) + ", " + getCharQuantity((980000100 + (100 * i))) + " players waiting, avg level is " + checkAVGLevel((980000100 + (100 * i))));
            } else if (getCharQuantity((980000101 + (100 * i))) == 0) {
                if (i <= 3)
                    buf.append("\r\n#L" + i + "# Carnival Field " + (i + 1) + "(2~4 ppl)#l");
                else
                    buf.append("\r\n#L" + i + "# Carnival Field " + (i + 1) + "(3~6 ppl)#l");
            }
        }
        if (buf.toString().equals("Sign up for Monster Carnival!#b"))
            return "Every Carnival Field is currently full. Try again later...";
        else
            return buf.toString();
    }

    public void setPartyRed() {
        for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
            MapleCharacter target = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
            if (target != null);
                target.setCPQTeam("red");
        }
    }

    public void setPartyBlue() {
        for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
            MapleCharacter target = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
            if (target != null);
                target.setCPQTeam("blue");
        }
    }

    public boolean checkPartyPlayersMap() {
        boolean yesno = true;
        for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
            MapleCharacter target = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
            if (target.getMapId() != getPlayer().getMapId())
                yesno = false;
        }
        return yesno;
    }

    public int checkAVGLevel(int map) {
        MapleMap mapz = c.getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld());
        List<MapleMapObject> players = mapz.getMapObjectsInRange(c.getPlayer().getPosition (), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.PLAYER));
        int level = 0;
        for (int a = 0; a < players.size(); a++) {
            MapleCharacter victim = (MapleCharacter) players.get(a);
            level += victim.getLevel();
        }
        return (level / players.size());
    }

    public void startClockTimer(final int map, int time) {
        getPlayer().getMap().broadcastMessage(MaplePacketCreator.getClock(time * 60));
        TimerManager.getInstance().schedule(new Runnable() {
            @Override
            public void run() {
                for (MaplePartyCharacter ch : getPlayer().getParty().getMembers()) {
                    MapleCharacter lol = getPlayer().getParty().getPlayer(getPlayer().getClient(), ch.getName());
                    lol.changeMap(lol.getClient().getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld()), lol.getClient().getChannelServer().getMapFactory().getMap(map, c.getPlayer().getWorld()).getPortal(0));
                }
            }
        }, (time * 60000));
    }

    public int getWorld() {
        return getPlayer().getWorld();
    }

    public void sendHint(String hint) {
        try {
            getClient().getChannelServer().getWorldInterface().broadcastMessage(null, MaplePacketCreator.sendHint(hint).getBytes());
        } catch (RemoteException e) {
            log.info("Error using cm.sendHint", e);
        }
    }

    public void openNpc(int npcz) {
        dispose();
        NPCScriptManager npcs = NPCScriptManager.getInstance();
        npcs.start(getClient(), npcz);
    }

    @Override
    public MapleQuestStatus.Status getQuestStatus(int id) {
        return getPlayer().getQuestStatus(id);
    }

    public boolean checkQuestStatus(int id, int how) {
        return MapleQuestStatus.Status.getById(how) == getQuestStatus(id);
    }
}
